﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Microsoft.Win32;
using System.IO;
using System.Windows.Interop;
using System.Diagnostics;
using System.Drawing;
using System.Windows.Media.Animation;
using ZmrSoft.ZmrImage;

namespace PngTool
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        #region 设置

        private bool _ShowToolbar = false;
        private bool _Register = false;

        #endregion

        private System.Drawing.Point _CenterPoint = new System.Drawing.Point(0, 0);
        private bool _SetCenterPointting = false;
        private List<SourceImage> _FileList = new List<SourceImage>();
        private SourceImage _CurSourceImage = null;

        private System.Windows.Point _p;
        private DateTime _MouseLeftButtonDownTime;

        public MainWindow(string FileName)
        {
            InitializeComponent();

            #region 初始化设置

            string oldValue = Registry.GetValue(@"HKEY_CLASSES_ROOT\.png", "", "") as string;
            _Register = (!string.IsNullOrEmpty(oldValue)) && oldValue.Equals("ZmrPng");

            #endregion

            #region 初始化界面

            //mOpenImage.Visibility = System.Windows.Visibility.Collapsed;
            //mSaveImage.Visibility = System.Windows.Visibility.Collapsed;
            //mShowToolbar.Visibility = System.Windows.Visibility.Collapsed;
            //mUnShowToolbar.Visibility = System.Windows.Visibility.Collapsed;

            #endregion

            #region 事件注册

            LocationChanged += (sender, e) =>
                {
                    if (!_SetCenterPointting)
                    {
                        _CenterPoint = new System.Drawing.Point((int)(Left + ActualWidth / 2), (int)(Top + ActualHeight / 2));
                    }
                };

            (this.Resources["styShowToolbar"] as Storyboard).Completed += (sender, e) =>
            {
                if (_ShowToolbar)
                {
                    frmToolbar.ShowToolbar();
                }
            };

            imgView.MouseLeave += (sender, e) =>
                {
                    frmToolbar.HideToolbar();
                    (this.Resources["styShowToolbar"] as Storyboard).Stop();
                };
            imgView.MouseMove += (sender, e) =>
                {
                    (this.Resources["styShowToolbar"] as Storyboard).Stop();
                    (this.Resources["styShowToolbar"] as Storyboard).Begin();

                    System.Windows.Point p = e.GetPosition(this);

                    if (p.X < imgView.ActualWidth / 4)
                    {
                        imgView.ToolTip = _CurSourceImage == null ? "右键打开或拖入png图片" : "上一张(左)";
                        this.Cursor = _CurSourceImage == null ? null : Cursors.ScrollW;
                    }
                    else if (p.X > imgView.ActualWidth / 4 * 3)
                    {
                        imgView.ToolTip = _CurSourceImage == null ? "右键打开或拖入png图片" : "下一张(右)";
                        this.Cursor = _CurSourceImage == null ? null : Cursors.ScrollE;
                    }
                    else
                    {
                        imgView.ToolTip = _CurSourceImage == null ? "右键打开或拖入png图片" : _CurSourceImage.ToHintString();
                        this.Cursor = null;
                    }
                };

            ContextMenuOpening += (sender, e) =>
                {
                    mSaveImage.IsEnabled = _CurSourceImage != null;
                    mShowToolbar.Visibility = _ShowToolbar ? System.Windows.Visibility.Collapsed : System.Windows.Visibility.Visible;
                    mUnShowToolbar.Visibility = _ShowToolbar ? System.Windows.Visibility.Visible : System.Windows.Visibility.Collapsed;

                    mRegister.Visibility = _Register ? System.Windows.Visibility.Collapsed : System.Windows.Visibility.Visible;
                    mUnRegister.Visibility = _Register ? System.Windows.Visibility.Visible : System.Windows.Visibility.Collapsed;
                };

            imgView.MouseLeftButtonUp += (sender, e) =>
                {
                    if (_MouseLeftButtonDownTime.AddSeconds(0.5) < DateTime.Now) return; //超过半秒则不认为是点击
                    if (_p.X < imgView.ActualWidth / 4)
                    {
                        ShowPiveImage();
                    }
                    else if (_p.X > imgView.ActualWidth / 4 * 3)
                    {
                        ShowNextImage();
                    }
                };
            imgView.MouseLeftButtonDown += (sender, e) =>
                {
                    _p = e.GetPosition(imgView);
                    _MouseLeftButtonDownTime = DateTime.Now;
                    this.DragMove();
                };

            imgView.AllowDrop = true;
            imgView.Drop += (sender, e) =>
                {
                    if (e.Data.GetDataPresent(DataFormats.FileDrop, false))
                    {
                        string fileName = (e.Data.GetData(DataFormats.FileDrop, false) as string[]).FirstOrDefault();
                        if ((File.Exists(fileName)) && (System.IO.Path.GetExtension(fileName).Equals(".png", StringComparison.CurrentCultureIgnoreCase)))
                        {
                            OpenImage(fileName);
                        }
                    }
                };

            MouseWheel += (sender, e) =>
                {
                    if (Keyboard.Modifiers == ModifierKeys.Control)
                    {
                        if (e.Delta > 0)
                        {
                            ZoomOut();
                        }
                        else
                        {
                            ZoomIn();
                        }
                    }
                };

            #endregion

            #region 右键菜单事件

            mOpenImage.Click += (sender, e) =>
                {
                    OpenImage();
                };

            mSaveToPng.Click += (sender, e) =>
                {
                    SaveImageToPng();
                };

            mSaveToIco.Click += (sender, e) =>
                {
                    SaveImageToIco();
                };

            mCloes.Click += (sender, e) =>
                {
                    Close();
                };

            mShowToolbar.Click += (sender, e) =>
                {
                    _ShowToolbar = true;
                };

            mUnShowToolbar.Click += (sender, e) =>
                {
                    _ShowToolbar = false;
                };

            mRegister.Click += (sender, e) =>
                {
                    Register();
                };

            mUnRegister.Click += (sender, e) =>
                {
                    UnRegister();
                };

            mAbout.Click += (sender, e) =>
                {
                    Process.Start(@"https://gitee.com/Zero_gitee");
                };

            #endregion

            #region 快捷键

            KeyDown += (sender, e) =>
                {
                    ShortcutKey(e);
                };

            #endregion

            if ((File.Exists(FileName)) && (System.IO.Path.GetExtension(FileName).Equals(".png", StringComparison.CurrentCultureIgnoreCase)))
            {
                OpenImage(FileName);
            }
        }

        ////保存界面元素为图片
        //private void SaveToImage(FrameworkElement p_FrameworkElement, string p_FileName)
        //{
        //    using (System.IO.FileStream fs = new System.IO.FileStream(p_FileName, System.IO.FileMode.Create))
        //    {
        //        RenderTargetBitmap bmp = new RenderTargetBitmap((int)p_FrameworkElement.ActualWidth, (int)p_FrameworkElement.ActualHeight, 1 / 96, 1 / 96, PixelFormats.Default);
        //        bmp.Render(p_FrameworkElement);
        //        BitmapEncoder encoder = new TiffBitmapEncoder();
        //        encoder.Frames.Add(BitmapFrame.Create(bmp));
        //        encoder.Save(fs);
        //    }
        //}

        #region 各功能的实现

        private void MoveByCenterPoint(int x, int y)
        {
            _SetCenterPointting = true;

            double left = Math.Max(x - imgView.Width / 2, 0);
            double top = Math.Max(y - imgView.Height / 2, 0);

            //Left = left;
            //Top = top;

            _SetCenterPointting = false;
        }

        private void RefreshCurImage()
        {
            if (_CurSourceImage != null)
            {
                Bitmap tmp = _CurSourceImage.ToDisplayImage();

                BitmapImage bmp = new BitmapImage();
                bmp.BeginInit();
                MemoryStream ms = new MemoryStream();
                tmp.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
                bmp.StreamSource = ms;
                bmp.EndInit();

                imgView.Width = Math.Max(tmp.Width, tmp.Height);
                imgView.Height = Math.Max(tmp.Width, tmp.Height);
                MoveByCenterPoint(_CenterPoint.X, _CenterPoint.Y);
                imgView.Stretch = Stretch.None;
                imgView.Source = bmp;
            }
            else
            {
                imgView.Source = null;
            }
        }

        #region 缩放

        //放大
        public void ZoomOut()
        {
            ZoomOut(10);
        }

        public void ZoomOut(int incremental)
        {
            if (_CurSourceImage != null)
            {
                _CurSourceImage.Zoom += incremental;
                RefreshCurImage();
            }
        }

        //缩小
        public void ZoomIn()
        {
            ZoomIn(10);
        }

        public void ZoomIn(int incremental)
        {
            if ((_CurSourceImage != null) && (_CurSourceImage.Zoom > 10))
            {
                _CurSourceImage.Zoom -= incremental;
                RefreshCurImage();
            }
        }

        #endregion

        #region 旋转

        //顺时针
        public void ClockwiseRotation()
        {
            ClockwiseRotation(90);
        }

        public void ClockwiseRotation(int angle)
        {
            if (_CurSourceImage != null)
            {
                _CurSourceImage.Angle += angle;
                RefreshCurImage();
            }
        }

        //逆时针
        public void CounterClockwiseRotation()
        {
            CounterClockwiseRotation(90);
        }

        public void CounterClockwiseRotation(int angle)
        {
            if (_CurSourceImage != null)
            {
                _CurSourceImage.Angle -= angle;
                RefreshCurImage();
            }
        }

        #endregion

        #region 翻转

        //上下
        public void ReversalUpDown()
        {
            if (_CurSourceImage != null)
            {
                _CurSourceImage.ReversalUpDown = !_CurSourceImage.ReversalUpDown;
                RefreshCurImage();
            }
        }

        //左右
        public void ReversalLeftRight()
        {
            if (_CurSourceImage != null)
            {
                _CurSourceImage.ReversalLeftRight = !_CurSourceImage.ReversalLeftRight;
                RefreshCurImage();
            }
        }

        #endregion

        #region 还原

        public void ReSet()
        {
            if (_CurSourceImage != null)
            {
                _CurSourceImage.Zoom = 100;
                _CurSourceImage.Angle = 0;
                _CurSourceImage.ReversalUpDown = false;
                _CurSourceImage.ReversalLeftRight = false;
                RefreshCurImage();
            }
        }

        #endregion

        #region 打开

        public void OpenImage()
        {
            OpenFileDialog od = new OpenFileDialog();
            od.Filter = @"png图片|*.png";
            if (od.ShowDialog().Value)
            {
                OpenImage(od.FileName);
            }
        }

        public void OpenImage(string fileName)
        {
            _FileList.Clear();

            if (File.Exists(fileName))
            {
                string path = System.IO.Path.GetDirectoryName(fileName);
                string[] files = Directory.GetFiles(path, "*.png");
                foreach (string f in files)
                {
                    _FileList.Add(new SourceImage(f));
                }
            }

            _CurSourceImage = _FileList.FirstOrDefault(Item => Item.FileName.Equals(fileName, StringComparison.CurrentCultureIgnoreCase));
            RefreshCurImage();
        }

        #endregion

        #region 保存

        public void SaveImageToPng()
        {
            if (_CurSourceImage != null)
            {
                SaveFileDialog sd = new SaveFileDialog();
                sd.Filter = @"png图片|*.png";
                sd.DefaultExt = ".png";
                sd.FileName = System.IO.Path.GetFileNameWithoutExtension(_CurSourceImage.FileName) + "[副本]";
                if (sd.ShowDialog().Value)
                {
                    if (File.Exists(sd.FileName))
                    {
                        File.Delete(sd.FileName);
                    }

                    _CurSourceImage.ToDisplayImage().Save(sd.FileName, System.Drawing.Imaging.ImageFormat.Png);
                }
            }
        }

        public void SaveImageToIco()
        {
            if (_CurSourceImage != null)
            {
                SaveFileDialog sd = new SaveFileDialog();
                sd.Filter = @"ico图标|*.ico";
                sd.DefaultExt = ".ico";
                sd.FileName = System.IO.Path.GetFileNameWithoutExtension(_CurSourceImage.FileName);
                if (sd.ShowDialog().Value)
                {
                    if (File.Exists(sd.FileName))
                    {
                        File.Delete(sd.FileName);
                    }

                    Bitmap bmp = _CurSourceImage.ToDisplayImage();
                    try
                    {
                        ZmrSoft.ZmrImage.IconDir icon = new ZmrSoft.ZmrImage.IconDir();
                        AddImage(icon, bmp, 16);
                        AddImage(icon, bmp, 24);
                        AddImage(icon, bmp, 32);
                        AddImage(icon, bmp, 48);
                        AddImage(icon, bmp, 64);
                        AddImage(icon, bmp, 72);
                        AddImage(icon, bmp, 96);
                        AddImage(icon, bmp, 128);
                        icon.SaveData(sd.FileName);
                    }
                    finally
                    {
                        bmp.Dispose();
                    }
                }
            }
        }

        private void AddImage(IconDir icon, Bitmap bmp, int size)
        {
            using (Bitmap tmp = new Bitmap(size, size))
            {
                using (Graphics g = Graphics.FromImage(tmp))
                {
                    g.DrawImage(bmp, 0, 0, size, size);
                }

                icon.AddImage(tmp, new System.Drawing.Rectangle(0, 0, size, size));
            }
        }

        #endregion

        #region 显示图片

        public void ShowNextImage()
        {
            int i = _FileList.IndexOf(_CurSourceImage) + 1;
            if (i < _FileList.Count)
            {
                _CurSourceImage.Zoom = 100;
                _CurSourceImage.Angle = 0;
                _CurSourceImage.ReversalUpDown = false;
                _CurSourceImage.ReversalLeftRight = false;

                _CurSourceImage = _FileList[i];
                RefreshCurImage();
            }
        }

        public void ShowPiveImage()
        {
            int i = _FileList.IndexOf(_CurSourceImage) - 1;
            if ((i >= 0) && (i < _FileList.Count))
            {
                _CurSourceImage.Zoom = 100;
                _CurSourceImage.Angle = 0;
                _CurSourceImage.ReversalUpDown = false;
                _CurSourceImage.ReversalLeftRight = false;

                _CurSourceImage = _FileList[i];
                RefreshCurImage();
            }
        }

        #endregion

        #region 关联png文件

        public void Register()
        {
            string self = System.AppDomain.CurrentDomain.SetupInformation.ApplicationBase + System.AppDomain.CurrentDomain.SetupInformation.ApplicationName;
            string applicationDataPath = System.Environment.GetFolderPath(System.Environment.SpecialFolder.LocalApplicationData);
            string applicationDataExePath = applicationDataPath + "\\" + System.AppDomain.CurrentDomain.SetupInformation.ApplicationName;
            if (!self.Equals(applicationDataExePath, StringComparison.CurrentCultureIgnoreCase))
            {
                File.Delete(applicationDataExePath);
                File.Copy(self, applicationDataExePath);
            }

            try
            {
                Registry.SetValue(@"HKEY_CLASSES_ROOT\ZmrPng\DefaultIcon", "", string.Format(@"{0}, 0", applicationDataExePath));
                Registry.SetValue(@"HKEY_CLASSES_ROOT\ZmrPng\shell\open\command", "", string.Format(@"{0} {1}", applicationDataExePath, "\"%1\""));
                Registry.SetValue(@"HKEY_CLASSES_ROOT\.png", "", "ZmrPng");
                var png = Registry.CurrentUser.GetValue(@"Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.png");
                if (png != null)
                {
                    Registry.CurrentUser.DeleteSubKeyTree(@"Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.png", false);
                }

                _Register = true;
            }
            catch (System.UnauthorizedAccessException e)
            {
                MessageBox.Show($"写入注册表失败，请尝试用管理员身份运行本程序。详情：{e.Message}");
            }
        }

        public void UnRegister()
        {
            string self = System.AppDomain.CurrentDomain.SetupInformation.ApplicationBase + System.AppDomain.CurrentDomain.SetupInformation.ApplicationName;
            string applicationDataPath = System.Environment.GetFolderPath(System.Environment.SpecialFolder.LocalApplicationData);
            string applicationDataExePath = applicationDataPath + "\\" + System.AppDomain.CurrentDomain.SetupInformation.ApplicationName;
            if (!self.Equals(applicationDataExePath, StringComparison.CurrentCultureIgnoreCase))
            {
                File.Delete(applicationDataExePath);
            }

            Registry.SetValue(@"HKEY_CLASSES_ROOT\.png", "", "PNGfile");
            Registry.ClassesRoot.DeleteSubKeyTree("ZmrPng", false);

            _Register = false;
        }

        #endregion

        #region 处理快捷键

        public void ShortcutKey(KeyEventArgs e)
        {
            if (Keyboard.Modifiers == ModifierKeys.Control)
            {
                if (e.KeyStates == Keyboard.GetKeyStates(Key.O))
                {
                    OpenImage();
                }
                else if (e.KeyStates == Keyboard.GetKeyStates(Key.S))
                {
                    SaveImageToPng();
                }
                else if (e.KeyStates == Keyboard.GetKeyStates(Key.I))
                {
                    SaveImageToIco();
                }
                else if ((e.KeyStates == Keyboard.GetKeyStates(Key.Add)) || (e.KeyStates == Keyboard.GetKeyStates(Key.OemPlus)))
                {
                    ZoomOut();
                }
                else if ((e.KeyStates == Keyboard.GetKeyStates(Key.Subtract)) || (e.KeyStates == Keyboard.GetKeyStates(Key.OemMinus)))
                {
                    ZoomIn();
                }
                else if ((Keyboard.GetKeyStates(Key.Up) == KeyStates.Down) && e.Key == Key.Right)
                {
                    ClockwiseRotation();
                }
                else if ((Keyboard.GetKeyStates(Key.Up) == KeyStates.Down) && e.Key == Key.Left)
                {
                    CounterClockwiseRotation();
                }
                else if ((e.KeyStates == Keyboard.GetKeyStates(Key.Up)) && (e.KeyStates == Keyboard.GetKeyStates(Key.Down)))
                {
                    ReversalUpDown();
                }
                else if ((e.KeyStates == Keyboard.GetKeyStates(Key.Left)) && (e.KeyStates == Keyboard.GetKeyStates(Key.Right)))
                {
                    ReversalLeftRight();
                }
                else if (e.KeyStates == Keyboard.GetKeyStates(Key.R))
                {
                    ReSet();
                }
            }
            else
            {
                if (e.Key == Key.Right)
                {
                    ShowNextImage();
                }
                else if (e.Key == Key.Left)
                {
                    ShowPiveImage();
                }
                else if (e.Key == Key.Escape)
                {
                    Close();
                }
                else if (e.Key == Key.Space)
                {
                    //frmToolbar.IsShowToolbar = !frmToolbar.IsShowToolbar;
                    frmToolbar.ShowToolbar();
                }
            }
        }

        #endregion

        #endregion
    }
}
